<template>
  <common-list-group class="report-component-wrap">
    <common-tree
      slot="group"
      ref="treeRef"
      :treeData="groupTreeData"
      :treeProp="groupTreeProp"
      isSlot
      :currentNodeKey="currentNodeKey"
      searchForChildren
      :default-expand-all="false"
      @getParentNodeData="getParentNodeData"
      :default-expanded-keys="treeIds"
      :setNodeByKey="'leaf'"
      isShowIconForNoChild
    >
      <div
        style="width: 100%"
        slot-scope="{ scope }"
        :class="[`offset-${scope.node.level}`]"
      >
        <div
          class="common-tree-node"
          :key="scope.data.id"
          @click="treeClick(scope.data, scope.node)"
        >
          <div class="tree-chart-type" v-if="scope.data.leaf">
            <!--            <i class="iconfont icon-youxiang"></i>-->
            <i :class="scope.data.chartType"></i>
          </div>

          <div :class="['tree-label', scope.data.leaf ? 'node' : 'group']">
            <common-carousel-text :content="scope.data.name" :font-size="14">
            </common-carousel-text>
          </div>

          <!--          <div :class="['tree-label',data.leaf ? 'node' : 'group']"-->
          <!--               @click.stop="treeClick(data,node)">-->
          <!--            {{ node.label }}-->
          <!--          </div>-->

          <el-popover
            placement="right-start"
            width="150"
            :offset="-2"
            v-model="scope.data.isPopover"
            trigger="hover"
            v-if="
              !scope.data.leaf &&
              scope.node.level < 2 &&
              scope.data.isDefault === 0
            "
            v-has-permi="[
              'system:reportparts:addNode',
              'system:reportparts:editNode',
              'system:reportparts:delNode',
            ]"
          >
            <div class="popover-button-container">
              <div
                class="button-item"
                v-if="!scope.data.leaf && scope.node.level < 2"
                @click.stop="addGroup(scope.data)"
                v-hasPermi="['system:reportparts:addNode']"
              >新增分类
              </div>
              <div
                class="button-item"
                v-if="!scope.data.leaf && scope.node.level > 1"
                @click.stop="editGroup(scope.data)"
                v-hasPermi="['system:reportparts:editNode']"
              >
                编辑分类
              </div>
              <div
                class="button-item"
                v-if="!scope.data.leaf"
                @click.stop="delGroup(scope.data)"
                v-hasPermi="['system:reportparts:delNode']"
              >
                删除分类
              </div>
            </div>
            <div class="tree-menu" slot="reference">
              <i class="iconfont icon-more"></i>
            </div>
          </el-popover>

          <el-popover
            placement="right-start"
            width="150"
            :offset="-2"
            v-model="scope.data.isPopover"
            trigger="hover"
            v-else-if="
              !scope.data.leaf &&
              1 < scope.node.level < 3 &&
              scope.data.isDefault === 0
            "
            v-has-permi="[
              'system:reportparts:editNode',
              'system:reportparts:delNode',
              'system:reportparts:addSubgroup',
            ]"
          >
            <div class="popover-button-container">
              <div
                class="button-item"
                v-if="!scope.data.leaf && scope.node.level > 1"
                @click.stop="editGroup(scope.data)"
                v-hasPermi="['system:reportparts:editNode']"
              >
                编辑分类
              </div>
              <div
                class="button-item"
                v-if="!scope.data.leaf"
                @click.stop="delGroup(scope.data)"
                v-hasPermi="['system:reportparts:delNode']"
              >
                删除分类
              </div>
              <div
                class="button-item"
                v-if="!scope.data.leaf && scope.node.level < 3"
                @click.stop="addComponent(scope.data)"
                v-hasPermi="['system:reportparts:addSubgroup']"
              >
                新增组件
              </div>
            </div>
            <div class="tree-menu" slot="reference">
              <i class="iconfont icon-more"></i>
            </div>
          </el-popover>

          <el-popover
            placement="right-start"
            width="150"
            :offset="-2"
            v-model="scope.data.isPopover"
            trigger="hover"
            v-else-if="scope.data.leaf && scope.data.isDefault === 0"
            v-has-permi="['system:reportparts:delSubgroup']"
          >
            <div class="popover-button-container">
              <div
                class="button-item"
                v-if="scope.data.leaf"
                @click.stop="delComponent(scope.data)"
                v-hasPermi="['system:reportparts:delSubgroup']"
              >
                删除组件
              </div>
            </div>
            <div class="tree-menu" slot="reference">
              <i class="iconfont icon-more"></i>
            </div>
          </el-popover>
        </div>
      </div>
    </common-tree>

    <chart-config
      :group-data="groupData"
      v-show="isChartConfig"
      slot="content"
      ref="ChartConfig"
      @update="updateTreeData"
    />
    <group-view
      slot="content"
      v-if="isGroupConfig"
      :info="groupInfo"
    ></group-view>

    <common-edit-dialog
      :visible="isGroupDialog"
      :title="isGroupEdit ? '编辑分类' : '新增分类'"
      :button-loading="isGroupLoading"
      width="400px"
      @cancel="cancel"
      @submit="persistenceData"
    >
      <el-form
        ref="groupForm"
        :model="groupForm"
        :rules="groupRules"
        label-width="100px"
      >
        <el-form-item label="分类名称" prop="name">
          <common-input v-model="groupForm.name" :maxlength="16"></common-input>
        </el-form-item>
      </el-form>
    </common-edit-dialog>
  </common-list-group>
</template>

<script>
import chartConfig from "./components/chartConfig";
import groupView from "./components/groupView";
import {
  subgroup_addType,
  subgroup_editType,
  subgroup_remove,
  subgroup_removeType,
  subgroup_tree,
} from "@/api/management/echart/subgroup";
import BaseList from "@/mixins/BaseList";

export default {
  name: "index",
  data() {
    return {
      treeIds: [],
      isChartConfig: false,
      isGroupConfig: false,
      groupInfo: {
        name: "",
        length: 0,
      }, // 点击分组展示的分组信息

      search: "",
      searchInterval: null,
      groupTreeData: [],
      groupTreeProp: {
        // 树参数
        children: "children",
        label: "name",
        isLeaf: "leaf",
      },
      // treeProp: {
      //   // 树参数
      //   children: "children",
      //   label: "label",
      //   disabled: false,
      // },
      menuId: null, // 当前分类id
      isPopoverStatus: false,
      isGroupDialog: false,
      isGroupEdit: false,
      isGroupLoading: false,
      groupForm: {
        id: null,
        parentId: null,
        name: null,
      },
      groupRules: {
        name: [{ required: true, message: "请输入分类名称", trigger: "blur" }],
      },
      chartIconList: [
        {
          type: "bar",
          icon: "iconfont icon-zhuzhuangtu",
        },
        {
          type: "line",
          icon: "iconfont icon-zhexiantu",
        },
        {
          type: "pie",
          icon: "iconfont icon-bingtu",
        },
        {
          type: "gauge",
          icon: "iconfont icon-yibiaopan",
        },
        {
          type: "funnel",
          icon: "iconfont icon-loudoutu",
        },
      ],
      groupData: [], // 仅含有菜单 不含数据
      currentNodeKey: "",
    };
  },
  mixins: [BaseList],
  components: {
    chartConfig,
    groupView,
  },
  methods: {
    /**
     * 过滤
     * @param data
     */
    getParentNodeData(data) {
      let index = this.groupTreeData.findIndex((f) => f.name.includes(data));
      if (index > -1) {
        this.groupInfo.name = this.groupTreeData[index].name;
        this.groupInfo.length =
          this.groupTreeData[index].children &&
          this.groupTreeData[index].children.length
            ? this.groupTreeData[index].children.reduce((r, c) => {
                return r + (c.children ? c.children.length : 0);
              }, 0)
            : 0;
      } else {
        let form = this.getNodeData(this.groupTreeData, data);
        this.groupInfo.name = form.name;
        this.groupInfo.length = form.children
          ? data
            ? form.children.length
            : form.children.reduce((r, c) => {
                return r + (c.children ? c.children.length : 0);
              }, 0)
          : 0;
      }
    },

    /**
     * 遍历树，获取当前筛选值的父节点数据
     * @param data
     * @param value
     */
    getNodeData(data, value) {
      let nodeData = {};
      if (data && data.length) {
        if (value || value === 0) {
          data.forEach((f) => {
            if (f.name.includes(value)) {
              if (!nodeData.id) {
                nodeData = f;
              }
            } else if (f.children && f.children.length > 0) {
              if (
                f.children.findIndex((v) => v.name.includes(value) && v.leaf) >
                -1
              ) {
                if (!nodeData.id) {
                  nodeData = f;
                }
              }
              if (!nodeData.id) nodeData = this.getNodeData(f.children, value);
            }
          });
        } else {
          nodeData = data[0];
        }
        return nodeData;
      }
    },

    treeClick(data, node) {
      if (data.leaf) {
        // 组件
        this.isChartConfig = true;
        this.isGroupConfig = false;
        this.$nextTick(() => {
          this.editConfigData(data.id, data);
        });
      } else {
        // 菜单
        let childNodes = 0;
        if (node.level == 1) {
          node.childNodes.forEach((item) => {
            childNodes += item.childNodes.length;
          });
        } else {
          childNodes = node.childNodes.length;
        }
        this.groupInfo.name = data.name;
        this.groupInfo.length = childNodes;
        this.isChartConfig = false;
        this.isGroupConfig = true;
      }
    },
    filterNode(value, data) {
      if (!value) return true;
      return data.name.indexOf(value) !== -1;
    },
    getChartIconByType(type) {
      let chartType = this.chartIconList.find((item) => item.type === type);
      if (chartType) return chartType.icon;
      return "";
    },
    handleTreeData(data) {
      // isPopover
      if (data && data instanceof Array) {
        data.forEach((d) => {
          d.isPopover = false;
          if (
            d.leaf &&
            d.componentVo &&
            d.componentVo.echart &&
            d.componentVo.echart.type
          ) {
            d.chartType = this.getChartIconByType(d.componentVo.echart.type);
          }
          this.handleTreeData(d.children);
        });
      }
    },
    handleGroupTreeData(data) {
      if (data && data instanceof Array) {
        return data.reduce((r, c) => {
          if (!c.leaf) {
            r.push({
              ...c,
              children:
                c.children && c.children instanceof Array
                  ? this.handleGroupTreeData(c.children)
                  : [],
            });
          }
          return r;
        }, []);
      } else {
        return data;
      }
    },
    searchTreeData() {
      // const clear = () => {
      //   if (this.searchInterval) {
      //     clearTimeout(this.searchInterval);
      //     this.searchInterval = null;
      //   }
      // };
      // clear();
      // this.searchInterval = setTimeout(() => {
      //   clear();
      //   this.getTree();
      // }, 1000);
    },
    getTree() {
      let params = {};
      if (this.search && this.search.length) params = { name: this.search };
      this.isGroupLoading = true;
      if (this.$refs.treeRef.getAllExpandedNodeIds().length) {
        this.treeIds = [
          ...this.treeIds,
          ...this.$refs.treeRef.getAllExpandedNodeIds(),
        ];
      }
      subgroup_tree(params)
        .then((res) => {
          if (res && res.code === 200) {
            if (!this.treeIds.length) {
              this.treeIds.push(res.data[0].id);
            }
            let treeData = res.data;
            this.handleTreeData(treeData);
            this.groupData = this.handleGroupTreeData(treeData);
            this.groupData.forEach((item) => {
              item.children.forEach((item) => {
                if (item.children.length == 0) {
                  return (item.children = null);
                }
              });
            });
            this.groupTreeData = treeData;
            let childNodes = 0;
            if (res.data && res.data.length) {
              let id = res.data[0].id;
              res.data[0].children.forEach((item, index, arr) => {
                if (item.parentId === id) {
                  childNodes += item.children.length;
                } else {
                  childNodes = arr.length;
                }
              });

              this.groupInfo.name = res.data[0].name;
              this.groupInfo.length = childNodes;
            } else {
              this.groupInfo.name = "";
              this.groupInfo.length = 0;
            }

            this.isChartConfig = false;
            this.isGroupConfig = true;
          } else {
            this.groupTreeData = [];
            this.handleListTips(res);
          }
        })
        .catch((err) => {
          this.groupTreeData = [];
          this.handleListTips(err);
        })
        .finally(() => {
          this.isGroupLoading = false;
        });
    },
    addGroup(data) {
      this.isChartConfig = false;
      this.isGroupConfig = true;
      this.groupInfo.name = data.name;
      data.isPopover = false;
      this.isGroupEdit = false;
      this.groupForm.parentId = data.id;
      this.groupForm.name = "";
      this.isGroupDialog = true;

      this.currentNodeKey = data.id;
      this.$refs.treeRef.$refs.tree.setCurrentKey(this.currentNodeKey);
    },
    editGroup(data) {
      this.isChartConfig = false;
      this.isGroupConfig = true;
      this.groupInfo.name = data.name;
      data.isPopover = false;
      this.isGroupEdit = true;
      this.groupForm.parentId = data.parentId;
      this.groupForm.id = data.id;
      this.groupForm.name = data.name;
      this.isGroupDialog = true;
      this.currentNodeKey = data.id;
      this.$refs.treeRef.$refs.tree.setCurrentKey(this.currentNodeKey);
    },
    delGroup(data) {
      this.isChartConfig = false;
      this.isGroupConfig = true;
      data.isPopover = false;
      this.groupInfo.name = data.name;

      if (
        data.children &&
        data.children instanceof Array &&
        data.children.length > 0
      ) {
        this.$GlobalErrorConfirm("警告", "当前分类下存在组件,不可以删除!");
      } else {
        this.$GlobalDeleteConfirm()
          .then(() => {
            subgroup_removeType({ ids: data.id })
              .then((res) => {
                if (res && res.code === 200) {
                  this.getTree();
                  this.$GlobalSuccessMessage("删除成功");
                } else {
                  this.$GlobalErrorConfirm("删除失败", res.msg);
                }
              })
              .catch((err) => {
                this.$GlobalErrorConfirm("删除失败", err.msg);
              });
          })
          .catch((err) => {});
      }
    },
    addComponent(data) {
      this.isChartConfig = true;
      this.isGroupConfig = false;
      data.isPopover = false;
      this.$nextTick(() => {
        this.addConfigData(data);
      });
      this.currentNodeKey = data.id;
      this.$refs.treeRef.$refs.tree.setCurrentKey(this.currentNodeKey);
    },
    delComponent(data) {
      data.isPopover = false;
      let message = (
        <p>
          <p>是否确认删除数据项?</p>
          <p style="font-size:12px">
            若删除,关联的报表配置和大屏配置数据也一并被删除!
          </p>
        </p>
      );
      this.$GlobalDeleteConfirm(message)
        .then(() => {
          subgroup_remove({ ids: data.id })
            .then((res) => {
              this.getTree();
              this.$GlobalSuccessMessage("删除成功");
            })
            .finally(() => {
              this.isChartConfig = false;
              this.isGroupConfig = false;
            });
        }).catch(()=>{});
    },
    updateTreeData() {
      // this.isChartConfig = false
      this.getTree();
    },
    cancel() {
      this.isGroupDialog = false;
      this.groupForm.id = null;
      this.groupForm.parentId = "";
      this.groupForm.name = "";
    },
    persistenceData() {
      this.$refs.groupForm.validate((valid) => {
        if (valid) {
          this.isGroupLoading = true;
          if (this.isGroupEdit) {
            subgroup_editType({
              id: this.groupForm.id,
              name: this.groupForm.name,
            })
              .then((res) => {
                if (res && res.code === 200) {
                  this.getTree();
                  this.$GlobalSuccessMessage("编辑成功");
                } else {
                  this.$GlobalErrorConfirm("编辑失败", res.msg);
                }
              })
              .catch((err) => {
                this.$GlobalErrorConfirm("编辑失败", err.msg);
              })
              .finally(() => {
                this.isGroupLoading = false;
                this.isGroupDialog = false;
              });
          } else {
            subgroup_addType({
              parentId: this.groupForm.parentId,
              name: this.groupForm.name,
            })
              .then((res) => {
                if (res && res.code === 200) {
                  this.getTree();
                  this.$GlobalSuccessMessage("新增成功");
                } else {
                  this.$GlobalErrorConfirm("新增成功", res.msg);
                }
              })
              .catch((err) => {
                this.$GlobalErrorConfirm("新增失败", err.msg);
              })
              .finally(() => {
                this.isGroupLoading = false;
                this.isGroupDialog = false;
              });
          }
        }
      });
    },

    getParentGroup(id) {
      let group = this.groupTreeData.find((item) => item.id === id);
      if (group) return group;
      this.groupTreeData.forEach((gi) => {
        let g = gi.children.find((item) => item.id === id);
        if (g) group = g;
      });
      return group;
    },

    addConfigData(data) {
      this.$refs.ChartConfig.addConfigData(data);
    },
    editConfigData(id, data) {
      let group = this.getParentGroup(data.parentId);
      this.$refs.ChartConfig.editConfigData(id, group);
    },
  },
  mounted() {
    this.getTree();
  },
};
</script>

<style scoped lang="scss">
.report-component-wrap {
  ::v-deep .report-tree-data-wrap {
    margin-top: 8px;
    max-height: calc(100% - 40px);
    overflow-y: scroll;
  }
}

::v-deep .common-tree-node {
  width: 100%;
  display: flex;
  align-items: center;

  .tree-chart-type {
    width: 14px;
    height: 14px;
    line-height: 14px;
    overflow: hidden;
    font-size: 12px;
    margin-right: 4px;

    i {
      font-size: 14px;
    }
  }

  .tree-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 14px;
  }

  .group {
    width: calc(100% - 18px);
  }

  .node {
    width: calc(100% - 36px);
  }

  .tree-menu {
    opacity: 0;
    width: 14px;
    height: 14px;
    line-height: 14px;
    font-size: 12px;
    margin-right: 4px;
    color: #909399;
  }

  &:hover {
    .tree-menu {
      opacity: 1;
    }
  }
}

::v-deep .offset-1 {
  width: 170px;
}

::v-deep .offset-2 {
  width: 160px;
}

::v-deep .offset-3 {
  width: 150px;
}

::v-deep .offset-4 {
  width: 140px;
}

.popover-button-container {
  display: flex;
  flex-direction: column;
  width: 100%;

  .button-item {
    height: 24px;
    line-height: 24px;
    margin-bottom: 4px;
    padding: 0 4px;
    cursor: pointer;

    &:last-child {
      margin-bottom: 0;
    }

    &:hover {
      background-color: #f5f7fa;
    }
  }
}
</style>
